package cwb1;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * This class represents an achievement.
 * 
 * @author Aurora
 *
 */
public class Achievement implements Data
{
	// The kind used by the database
	private static final String KIND = "Achievement";
	// The name of the achievement.
	private String achievementName;
	// The number of the achievement
	private long achievementNumber;
	// The description of the achievement
	private String achievementDescription;
	// The type of the activity
	private long achievementType;
	// The id of the achievement
	private String achievementId;
	// The amount to reach.
	private long amountToReach;
	// The option corresponding to the purpose of the achievement.
	private long option;
	// The date of the begin of the period
	private Date startDate;
	// The date of the end of the period
	private Date stopDate;
	// The list of all the userId's
	private ArrayListMap<String> users;
	
	private long eventType;
	private final int AMOUNT_OF_IMPORTANT_FIELDS = 10;
	
	/**
	 * This method makes an achievement object.
	 * 
	 * @param achievementName The name of the achievement
	 * @param achievementNumber The number of the achievement
	 * @param achievementDescription The description of the achievement
	 * @param activityType The type of the activity
	 * @param amountToReach The amount to reach
	 * @param option The option corresponding to the purpose of the achievement
	 * @param startDate The date of the begin of the period
	 * @param stopDate The date of the end of the period
	 */
    public Achievement(String achievementName, long achievementNumber, String achievementDescription, long achievementType
    		, long amountToReach, long option, Date startDate, Date stopDate, long eventType)
	{
    	this.achievementName = achievementName;
    	this.achievementNumber = achievementNumber;
    	this.achievementDescription = achievementDescription;
    	this.achievementType = achievementType;
    	this.amountToReach = amountToReach;
    	this.option = option;
    	this.startDate = startDate;
    	this.stopDate = stopDate;
    	this.eventType = eventType;
    	
    	achievementId = achievementName;
    	
    	users = new ArrayListMap<String>();
    }
    
    /**
     * Makes a new achievement using the values of the map. Be careful that the keys correspond with the field names of the achievement. 
     * Their is no control.
     * 
     * @param values The map with the values, having keys: "achievementName" with String, "achievementNumber" with long, "achievementDescription" with String, "achievementType" with long, "achievementId" with String, "amountToReach" with long, "option" with long, "startDate" with Date, "stopDate" with Date.
     */
    public Achievement(Map<String,Object> properties) {
    	achievementName = (String) properties.get("achievementName");
    	achievementNumber = (Long) properties.get("achievementNumber");
    	achievementDescription = (String) properties.get("achievementDescription");
    	achievementType = (Long) properties.get("achievementType");
    	amountToReach = (Long) properties.get("amountToReach");
    	option = (Long) properties.get("option");
    	startDate = (Date) properties.get("startDate");
    	stopDate = (Date) properties.get("startDate");
    	achievementId = (String) properties.get("achievementId");
    	eventType = (Long) properties.get("eventType"); 
    	
    	users = new ArrayListMap<String>(properties, properties.size() - AMOUNT_OF_IMPORTANT_FIELDS);
    }
    
    /**
     * This method returns the name of the achievement.
     * 
     * @return achievementName: The name of the achievement.
     */
    public String getAchievementName()
    {
    	return achievementName;
    }
    
    /**
     * This method returns the number of the achievement.
     * 
     * @return achievementNumber: The number of the achievement.
     */
    public long getAchievementNumber()
    {
    	return achievementNumber;
    }
    
    /**
     * This method returns the description of the achievement.
     * 
     * @return achievementDescription: The description of the achievement.
     */
    public String getAchievementDescription()
    {
    	return achievementDescription;
    }
    
    /**
     * This method changes the name of the achievement to the given name.
     * 
     * @param newName The new name of the achievement.
     */
    public void getAchievementName(String newName)
    {
    	achievementName = newName;
    }
    
    /**
     * This method changes the description of the achievement to the given discription.
     * 
     * @param newDescription The new description of the achievement.
     */
    public void getAchievementDescription(String newDescription)
    {
    	achievementDescription = newDescription;
    }
    
    /**
     * Returns the type of the achievement.
     * 
     * @return The type of the achievement.
     */
    public long getAchievementType()
    {
    	return achievementType;
    }
    
    /**
     * Changes the type of the achievement to the given value.
     * 
     * @param achievementType The new type of the achievement.
     */
    protected void setAchievementType(long achievementType)
    {
    	this.achievementType = achievementType;
    }
    
    /**
     * Returns the id of the achievement.
     * 
     * @return The id of the achievement
     */
    public String getId()
    {
    	return achievementId;
    }
    
    /**
     * Returns the kind of the achievement, used by the google database.
     * 
     * @return The kind of the achievement.
     */
    public String getKind()
    {
    	return KIND;
    }
    
    /**
     * Returns the kind of the achievement, used by the google database.
     * 
     * @return The kind of the achievement.
     */
    public static String staticGetKind()
    {
    	return KIND;
    }
    
    /**
     * Returns the fields of the achievement in a HashMap, necessary for the DataEngine.
     * 
     * @return A HashMap filled with the fields of the achievement and the key as fieldname.
     */
    public HashMap<String,Object> getProperties()
    {
    	HashMap<String, Object> properties = new HashMap<String,Object>(users.getProperties());
    	properties.put("achievementName", achievementName);
    	properties.put("achievementNumber", achievementNumber);
    	properties.put("achievementDescription", achievementDescription);
    	properties.put("achievementType", achievementType);
    	
    	properties.put("achievementId", achievementId);
    	properties.put("amountToReach", amountToReach);
    	properties.put("option", option);
    	properties.put("startDate", startDate);
    	
    	properties.put("stopDate", stopDate);
    	properties.put("eventType", eventType);
    	
    	
    	return properties;
    }
    
    public long getEventType() {
    	return eventType;
    }
    
    /**
     * Verifies the achievement with the given achievement.
     * They are the same when the id's of the achievement are the same.
     * 
     * @param achievement The achievement to compare with.
     * @return True when they are the same. False when they are not the same.
     */
    public boolean equals(Achievement achievement)
    {
    	return achievementId.equals(achievement.getId());
    }
	
	public long getAmountToReach()
	{
		return amountToReach;
	}
	
	public long getOption()
	{
		return option;
	}

	public static String getStaticKind() {
		return KIND;
	}

    
	
	public Date getStartDate()
	{
		return startDate;
	}
	
	public Date getStopDate()
	{
		return stopDate;
	}
	
	public void addUser(User user) {
		users.add(user.getId());
	}
}